
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/module.h>
#include <asm/uaccess.h>    

#define HELLO_MAGIC 'k'
#define S_R    (0x0a)	//_IO(HELLO_MAGIC,0x1a)
#define S_W    (0x0c)	//_IO(HELLO_MAGIC,0x1b)

static 	char buf[256];
static int nr;

static int misc_open (struct inode *node, struct file *file)
{
	nr = 0;
	printk("misc open ok...\n");

	return 0;
}

static ssize_t misc_read(struct file *file, char *buffer, size_t size, loff_t *loff)
{
	
	copy_to_user(buffer, buf, nr);

	return 0;
}

static ssize_t misc_write(struct file *file, const char *buffer, size_t size, loff_t *loff)
{


	copy_from_user(buf, buffer,size);

	printk("buffer: %s\n", buffer);
	printk("size: %d\n", size);
	printk("loff: %d\n", loff);
	nr = size;

	printk("write buf: %s\n", buf);


	return 0;
}

/**
 * @brief      ioctl
 *
 * @param      file  file pointer
 * @param[in]  cmd   ioctl cmd
 * @param[in]  arg   input argv, memery addr.
 *
 * @return     { description_of_the_return_value }
 */
static long misc_unlocked_ioctl(struct file *file , unsigned int cmd, unsigned long arg)
{
	printk("unlocked_ioctl ....\n");

	char *rbuf[256], *wbuf[256];
	static cnt = 0;

	// arg:  memery addr.
	printk("cmd: %d, arg:%d\n", cmd, (int *)arg);

	switch(cmd)
	{
		case S_R:
		{
			
			copy_to_user((int *)arg, rbuf, 256);
			break;
		}

		case S_W:
		{
			memset(rbuf, '\0', sizeof(rbuf));
			copy_from_user(rbuf, (char *)arg, 256);
			printk("read msg: %s\n", rbuf);
			break;
		}

	}



	return 0;
}

static const struct file_operations fram_fops = {
	.owner			= THIS_MODULE,
	.open = misc_open,
	.read = misc_read,
	.write = misc_write,
	.unlocked_ioctl = misc_unlocked_ioctl,
};

static struct miscdevice misc_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "my_misc",
	.fops = &fram_fops
};

static int __init misc_init(void)
{
	int ret;

	ret = misc_register(&misc_dev);
	if (ret) {
		printk("misc_reg err\n");
		return ret;
	}
	
	printk("misc_reg ok\n");

	return 0;
}

static void __exit msic_eixt(void)
{
	misc_deregister(&misc_dev);
}

module_init(misc_init);
module_exit(msic_eixt);

MODULE_LICENSE("GPL");

